package it.scambiocorse.dao;

import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.jdbc.support.nativejdbc.SimpleNativeJdbcExtractor;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import it.scambiocorse.model.AreaType;
import it.scambiocorse.model.ClienteType;
import it.scambiocorse.model.JTableType;
import it.scambiocorse.model.ServizioJson;
import it.scambiocorse.rowmapper.AreaRowMapper;
import it.scambiocorse.rowmapper.AutistaRowMapper;
import it.scambiocorse.rowmapper.ClienteRowMapper;
import it.scambiocorse.rowmapper.ClientiRowMapper;
import it.scambiocorse.utils.Utils;

public class ClienteDao extends JdbcDaoSupport implements ClienteService {

	final Logger logger = Logger.getLogger(getClass());

	  protected void initDao() throws Exception {
	    super.initDao();
	    getJdbcTemplate().setNativeJdbcExtractor(new SimpleNativeJdbcExtractor());
	  }
	  
	  
	public ClienteType getCliente(int idCliente) throws Exception {
		ClienteType ret = new ClienteType();
		
	String metodo = "getCliente(...)";
	logger.warn(metodo+" - Inizio");
	  
	String sql = "select * from cliente_tab where id_cliente = ?";
	  try{ 
	  	
	  	logger.warn(metodo+" - Chiamata SQL = "+sql+" ? = "+idCliente);
	  	ret =  (ClienteType) getJdbcTemplate().queryForObject(sql, new Object[] { idCliente }, new ClienteRowMapper());
	  	logger.warn(metodo+" Esito: OK, cliente estratto");
	  // Do whatever I want with resultset here... 
	  } catch (Exception e) {
	  	logger.warn(metodo+" Si e' verificato un errore GENERICO durante la seguente chiamata  \""+sql);
	  	logger.error(e);
	  	throw e;
	  }
	  
	  logger.warn(metodo+"La lista e' "+((ret == null) ? "NULL" : "PIENA"));
	  logger.warn(metodo+" Fine");		
		
		return ret;
	}
	
	
	@Transactional(
		    propagation = Propagation.NESTED,
		    isolation = Isolation.DEFAULT,
		    readOnly = false)
	public boolean inserisciCliente(ClienteType c) throws Exception {
			String metodo = "inserisciCliente(...) - ";
			boolean ret = false;
			logger.warn(metodo+"Inizio");
		  String sql = "insert into cliente_tab (id_serv_user, desc_nome, tel, email) values(?,?,?) where id_cliente = ?";
		  logger.warn(metodo+ " "+sql+" -----> id_cliente ="+c.getIdCliente());
		  try{ 
				
			  // IMPOSTO ID_SERV_USER
			  	int idServCliente = 1;
				  sql = "select max(id_cliente_user)+1 from cliente_tab where id_user_inse = ?";
				  idServCliente = getJdbcTemplate().queryForInt(sql, new Object[] {c.getIdUser()});  
//				  
//				  if (idServCliente == 0) {
//					  idServCliente = 1; //NEL CASO DI PRIMO INSERIMENTO 
//				  }
				  c.setIdUser(idServCliente);
			  
		  	 int check = getJdbcTemplate().update(sql, new Object[] {c.getDescNome(), c.getTelefono(), c.getIdCliente() });
		  	 if (check > 0) {
		  	 	ret = true;
		  	 }
		  	
		  	
		  } catch (Exception e) {
		  	logger.warn(metodo+" Si e' verificato un errore GENERICO durante la seguente chiamata "+sql);
		  	logger.error(e);
		  	throw e;
		  }
		  
		  logger.warn(metodo+" Fine");
		return ret;
		  
		}
	
	
	@Transactional(
		    propagation = Propagation.NESTED,
		    isolation = Isolation.DEFAULT,
		    readOnly = false)
	public int inserisciClienteInt(ClienteType c) throws Exception {
			String metodo = "inserisciCliente(...) - ";
			boolean ret = false;
			logger.warn(metodo+"Inizio");
		  String sql = "insert into cliente_tab (id_user_inse, desc_nome, tel, email, data_inse) values(?,?,?,?,?)";
		  logger.warn(metodo+ " "+sql+" -----> id_cliente ="+c.getIdCliente());
		  int idCliente = 1;
		  try{ 
				
				NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(this.getDataSource());
				KeyHolder keyHolder = new GeneratedKeyHolder();
				this.getJdbcTemplate().update(new PSCCliente(c),keyHolder);
	
	

				idCliente = keyHolder .getKey().intValue();
			  
			  
//			  
//		  	 int check = getJdbcTemplate().update(sql, new Object[] {c.getIdUser(), c.getDescNome(), c.getTelefono(), c.getIdCliente(), Utils.getSysDate() });
//		  	 if (check > 0) {
//		  	 	ret = true;
//		  	 }
		  	
		  	
		  } catch (Exception e) {
		  	logger.warn(metodo+" Si e' verificato un errore GENERICO durante la seguente chiamata "+sql);
		  	logger.error(e);
		  	throw e;
		  }
		  
		  logger.warn(metodo+" Fine");
		return idCliente;
		  
		}
	
	
	
	@Transactional(
		    propagation = Propagation.NESTED,
		    isolation = Isolation.DEFAULT,
		    readOnly = false)
	public boolean modificaCliente(ClienteType c) throws Exception {
			String metodo = "modificaCliente(...) - ";
			boolean ret = false;
			logger.warn(metodo+"Inizio");
		  String sql = "update cliente_tab set desc_nome = ?, tel = ?, email = ? where id_cliente = ?";
		  logger.warn(metodo+ " "+sql+" -----> id_cliente ="+c.getIdCliente());
		  try{ 
				
		  	 int check = getJdbcTemplate().update(sql, new Object[] {c.getDescNome(), c.getTelefono(), c.getIdCliente() });
		  	 if (check > 0) {
		  	 	ret = true;
		  	 }
		  	
		  	
		  } catch (Exception e) {
		  	logger.warn(metodo+" Si e' verificato un errore GENERICO durante la seguente chiamata "+sql);
		  	logger.error(e);
		  	throw e;
		  }
		  
		  logger.warn(metodo+" Fine");
		return ret;
		  
		}
	
	
	public ArrayList<ClienteType> listaClienti(int idSogg) throws Exception {
		String metodo = "listaClienti(...)";
		logger.warn(metodo+" - Inizio");
	  ResultSet rs = null; 
	  List ret = null;
	  String sql = "SELECT * FROM cliente_tab where id_user_inse = ?";
	  try{ 
	  	
	  	logger.warn(metodo+" - Chiamata SQL = "+sql+" ? = "+idSogg);
	  	ret = (List<ClienteType>) getJdbcTemplate().query(sql, new Object[] { idSogg }, new ClientiRowMapper());
	  	logger.warn(metodo+" Esito: OK, grandezza lista "+ret.size());
	  
	  logger.warn(metodo+"La lista e' "+((ret == null) ? "NULL" : "PIENA"));
	  logger.warn(metodo+" Fine");
	  
		return (ArrayList<ClienteType>)ret;
	  
	  } catch (Exception e) {
	  	logger.warn(metodo+" Si e' verificato un errore GENERICO durante la seguente chiamata  \""+sql);
	  	logger.error(e);
	  	throw e;
	  }
	}
	
	 public HashMap listaClientiIdUserJTable(int idUser, JTableType j) throws Exception {
			String metodo = "listaClientiIdUserJTable(...) - ";
			logger.warn(metodo+"Inizio");
			  List ret = null;
			  String sql = "";
			  	HashMap jOut = null;
				try{ 	
						 Object[] args = null;
						  
						  if (Utils.isValid(j.getJtSorting())) { // AJAX CON SORTING & PAGING
							  sql = "select * from cliente_tab where id_user_inse = ? ORDER BY "+decodeClienteColumn(j.getJtSorting())+" LIMIT ?,?";
							  logger.warn("Select con SORTING & PAGING");
//							  String orderBy = decodeColumn(j.getJtSorting());
//							  args = new Object[] { idUser, i, k, "s."+orderBy, j.getJtStartIndex(),j.getJtPageSize() };
							  args = new Object[] { idUser, j.getJtStartIndex(),j.getJtPageSize() };
							  
							  
						  } else {										// AJAX SOLO PAGING
							  sql = "select * from cliente_tab where id_user_inse = ? LIMIT ?,?";
							  logger.warn("Select con SOLO con PAGING -- jtStartIndex = "+j.getJtStartIndex()+" jtPageSize = "+j.getJtPageSize());
							  args = new Object[] { idUser, j.getJtStartIndex(),j.getJtPageSize() };
						  }
						  
					  
						  	logger.warn(metodo+" - Chiamata SQL = "+sql+" ? = "+idUser);
						  	ret = (List<ServizioJson>) getJdbcTemplate().query(sql, args , new ClienteRowMapper());
						  	logger.warn( metodo+" Esito: OK, grandezza lista "+ret.size() );
						  	
						  	int totRows = 0;
						  	if (ret.size() > 0) {
								logger.warn("PRENDO IL TOTALE PER JTABLE");
							  	sql = "SELECT count(*) FROM cliente_tab s where s.id_user_inse = ?";
								totRows =  getJdbcTemplate().queryForInt(sql, args = new Object[] { idUser } );
						  	}
						  	
						  	
						  	
						  	jOut = new HashMap<String, Object>();
							jOut.put("Result", "OK");
							jOut.put("Records", ret);
							jOut.put("TotalRecordCount", totRows);
			
						  	logger.warn( metodo+" Esito: OK, grandezza lista "+ret.size() );
				  } catch (Exception e) {
				  	logger.warn(metodo+" Si e' verificato un errore GENERICO durante la seguente chiamata  \""+sql);
				  	logger.error(e);
				  	throw e;
				  }
		  
		    logger.warn(metodo+" Fine");
			return jOut;
		}


	private String decodeClienteColumn(String jtSorting) {
		// TODO Auto-generated method stub
		return null;
	}

}
